home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Gold Collection / Software Vault - The Gold Collection (American Databankers) (1993).ISO / cdr05 / shwdib.zip / DLGOPEN.C < prev    next >
C/C++ Source or Header  |  1993-07-26  |  17KB  |  454 lines

  1. /*******************************************************************************
  2.  *                                                                             *
  3.  *  MODULE      : DLGOPEN.C                                                    *
  4.  *                                                                             *
  5.  *  DESCRIPTION : Routines to display a standard File/Open and File/Save       *
  6.  *                dialog boxes.                                                *
  7.  *                                                                             *
  8.  *  FUNCTIONS   : DlgOpenFile() - Displays a dialog box for opening or saving a*
  9.  *                                file.                                        *
  10.  *                                                                             *
  11.  *                DlgfnOpen()   - Dialog function for the above dialog.        *
  12.  *                                                                             *
  13.  *                AddExt()      - Adds an extension to a filename if not       *
  14.  *                                already present.                             *
  15.  *                                                                             *
  16.  *                FSearchSpec() - Checks if given string contains a wildcard   *
  17.  *                                character.                                   *
  18.  *                                                                             *
  19.  *                FillListBox() - Fills listbox with files that match specs.   *
  20.  *                                                                             *
  21.  *                DlgCheckOkEnable() - Enables <OK> button iff there's text in *
  22.  *                                     the edit control.                       *
  23.  *                                                                             *
  24.  *                NOTE : These routines require that the app. be running       *
  25.  *                       SS = DS since they use near pointers into the stack.  *
  26.  *                                                                             *
  27.  *******************************************************************************/
  28. // COPYRIGHT:
  29. //
  30. //   (C) Copyright Microsoft Corp. 1992.  All rights reserved.
  31. //
  32. //   You have a royalty-free right to use, modify, reproduce and
  33. //   distribute the Sample Files (and/or any modified version) in
  34. //   any way you find useful, provided that you agree that
  35. //   Microsoft has no warranty obligations or liability for any
  36. //   Sample Application Files which are modified.
  37. #include <windows.h>
  38. #include "showdib.h"
  39.  
  40. static PSTR szExt;
  41.  
  42. static PSTR szFileName;
  43.  
  44. static PSTR szTitle;
  45.  
  46. static DWORD flags;
  47.  
  48. static WORD fOpt;
  49.  
  50. /* Forward declarations of helper functions */
  51.  
  52.  
  53. static void NEAR DlgCheckOkEnable (HWND hwnd, int idEdit, unsigned message);
  54. static char *NEAR FillListBox (HWND, char *);
  55. static BOOL NEAR FSearchSpec (char *);
  56. static void NEAR AddExt (char *, char *);
  57. extern PASCAL chdir (LPSTR);              /* in dlgopena.asm */
  58. #define DLGOPEN_UNUSED   0
  59.  
  60. /* Mask to eliminate bogus style and bitcount combinations ...
  61.  * RLE formats, if chosen should be matched with the bitcounts:
  62.  *   RLE4 scheme should be used only for 4 bitcount DIBs.
  63.  *   RLE8   "      "     "   "   "    "  8   "       "
  64.  *
  65.  * BITCOUNTMASK is indexed by DLGOPEN_RLE4 >> 4, DLGOPEN_RLE8 >> 4
  66.  * and DLGOPEN_RLE8 >> 4
  67.  */
  68.  
  69. static WORD BITCOUNTMASK[] =
  70. {
  71.    DLGOPEN_UNUSED,
  72.    DLGOPEN_1BPP | DLGOPEN_8BPP | DLGOPEN_24BPP,
  73.    DLGOPEN_1BPP | DLGOPEN_4BPP | DLGOPEN_24BPP,
  74.    DLGOPEN_UNUSED,
  75.    0
  76. };
  77.  
  78. /****************************************************************************
  79.  *                                                                          *
  80.  *  FUNCTION   :DlgfnOpen (hwnd, msg, wParam, lParam)                       *
  81.  *                                                                          *
  82.  *  PURPOSE    :Dialog function for File/Open dialog.                       *
  83.  *                                                                          *
  84.  ****************************************************************************/
  85.  
  86.  
  87. int far PASCAL DlgfnOpen (hwnd, msg, wParam, lParam)
  88. HWND hwnd;
  89. unsigned msg;
  90. WORD wParam;
  91. LONG lParam;
  92. {
  93.    int result = -1;    /* Assume illegal filename initially */
  94.    WORD w;
  95.    char c;
  96.    WORD f;
  97.    OFSTRUCT of;
  98.    RECT rc, rcCtl;
  99.    HWND hwndT;
  100.    BOOL fEnable;
  101.  
  102.    switch (msg)
  103.       {
  104.    case WM_INITDIALOG:
  105.       if (szTitle && *szTitle)
  106.          SetWindowText(hwnd, szTitle);
  107.  
  108.       /* Set text on <OK> button according to mode (File/Open or File/Save) */
  109.       if (flags & OF_SAVE)
  110.          SetDlgItemText(hwnd, IDOK, "&Save");
  111.       if (flags & OF_OPEN)
  112.          SetDlgItemText(hwnd, IDOK, "&Open");
  113.       if ((flags & OF_NOOPTIONS) && (hwndT = GetDlgItem(hwnd, DLGOPEN_FOLDOUT))
  114.       )
  115.          EnableWindow(hwndT, FALSE);
  116.       if (hwndT = GetDlgItem(hwnd, DLGOPEN_SMALL))
  117.       {
  118.          GetWindowRect(hwnd, &rc);
  119.          GetWindowRect(GetDlgItem(hwnd, DLGOPEN_SMALL), &rcCtl);
  120.          SetWindowPos(hwnd, NULL, 0, 0, rcCtl.left - rc.left, rc.bottom - rc.
  121.                       top, SWP_NOZORDER | SWP_NOMOVE);
  122.       }
  123.       /* fill list box with filenames that match specifications, and
  124.        * fill static field with path name.
  125.        */
  126.       FillListBox(hwnd, szExt);
  127.  
  128.       /* If in Save mode, set the edit control with default (current)
  129.        * file name,and select the corresponding entry in the listbox.
  130.        */
  131.       if ((flags & OF_SAVE) && *szFileName)
  132.       {
  133.          SetDlgItemText(hwnd, DLGOPEN_EDIT, szFileName);
  134.          SendDlgItemMessage(hwnd, DLGOPEN_FILE_LISTBOX, LB_SELECTSTRING, 0, (
  135.                             LONG)(LPSTR)szFileName);
  136.       }
  137.       else
  138.       {
  139.          /*  Set the edit field with the default extensions... */
  140.          if (flags & OF_NOSHOWSPEC)
  141.             SetDlgItemText(hwnd, DLGOPEN_EDIT, "");
  142.          else
  143.             SetDlgItemText(hwnd, DLGOPEN_EDIT, szExt);
  144.       }
  145.       /*  ...and select all text in the edit field */
  146.       SendDlgItemMessage(hwnd, DLGOPEN_EDIT, EM_SETSEL, 0, 0x7FFF0000L);
  147.  
  148.       /*  check all options that are set */
  149.       for (f = DLGOPEN_1BPP; f; f <<= 1)
  150.          CheckDlgButton(hwnd, FID(f), fOpt & f);
  151.       break;
  152.  
  153.    case WM_COMMAND:
  154.       w = wParam;
  155.       switch (w)
  156.          {
  157.       case IDOK:
  158.          if (IsWindowEnabled(GetDlgItem(hwnd, IDOK)))
  159.          {
  160.             /* Get contents of edit field and add search spec. if it
  161.              * does not contain one.
  162.              */
  163.             GetDlgItemText(hwnd, DLGOPEN_EDIT, (LPSTR)szFileName, 128);
  164.             w = lstrlen(szFileName) - 1;
  165.             c = szFileName[w];
  166.             switch (c)
  167.                {
  168.             case '\\':
  169.  
  170.             case '/':
  171.                szFileName[w] = 0;
  172.                break;
  173.                }
  174.             if (chdir((LPSTR)szFileName))
  175.                lstrcpy(szFileName, szExt);
  176.  
  177.             /*  Try to open path.  If successful, fill listbox with
  178.              *  contents of new directory.  Otherwise, open datafile.
  179.              */
  180.             if (FSearchSpec(szFileName))
  181.             {
  182.                lstrcpy(szExt, FillListBox(hwnd, szFileName));
  183.                if (flags & OF_NOSHOWSPEC)
  184.                   SetDlgItemText(hwnd, DLGOPEN_EDIT, "");
  185.                else
  186.                   SetDlgItemText(hwnd, DLGOPEN_EDIT, szExt);
  187.                break;
  188.             }
  189.  
  190.             /*  Make filename upper case and if it's a legal DOS
  191.              *  name, try to open the file.
  192.              */
  193.             AnsiUpper(szFileName);
  194.             AddExt(szFileName, szExt);
  195.             result = OpenFile(szFileName, &of, (WORD)flags);
  196.             if (result != -1)
  197.             {
  198.                lstrcpy(szFileName, of.szPathName);
  199.             }
  200.             else if (flags & OF_MUSTEXIST)
  201.             {
  202.                MessageBeep(0);
  203.                return 0L;
  204.             }
  205.  
  206.             /*  Get the state of all checked options */
  207.             for (f = DLGOPEN_1BPP; f; f <<= 1)
  208.             {
  209.                if (IsDlgButtonChecked(hwnd, FID (f)))
  210.                   fOpt |= f;
  211.                else
  212.                   fOpt &= ~f;
  213.             }
  214.             EndDialog(hwnd, result);
  215.          }
  216.          break;
  217.  
  218.       case DLGOPEN_OPTION + DLGOPEN_RLE4:
  219.  
  220.       case DLGOPEN_OPTION + DLGOPEN_RLE8:
  221.  
  222.       case DLGOPEN_OPTION + DLGOPEN_RGB:
  223.          /* Mask out incompatible bitcount options and gray the
  224.           * appropriate radiobuttons.
  225.           */
  226.          for (f = DLGOPEN_1BPP; f <= DLGOPEN_24BPP; f <<= 1)
  227.          {
  228.             fEnable = !(f & BITCOUNTMASK[IDF(w) >> 4]);
  229.             EnableWindow(GetDlgItem(hwnd, FID(f)), fEnable);
  230.  
  231.             /* If the radiobutton is being grayed, uncheck it and
  232.              * and check an "allowed" option so the bitcount group
  233.              * is still accessible via the keyboard
  234.              */
  235.             if (!fEnable && IsDlgButtonChecked(hwnd, FID (f)))
  236.             {
  237.                CheckDlgButton(hwnd, FID(f), FALSE);
  238.                CheckDlgButton(hwnd, FID(IDF(w) >> 3), TRUE);
  239.             }
  240.          }
  241.          break;
  242.  
  243.       case IDCANCEL:
  244.          /* User pressed cancel.  Just take down dialog box. */
  245.          EndDialog(hwnd, 0);
  246.          break;
  247.  
  248.       /*  User single clicked or doubled clicked in listbox -
  249.        *  Single click means fill edit box with selection.
  250.        *  Double click means go ahead and open the selection.
  251.        */
  252.  
  253.       case DLGOPEN_FILE_LISTBOX:
  254.  
  255.       case DLGOPEN_DIR_LISTBOX:
  256.          switch (HIWORD(lParam))
  257.             {
  258.          /* Single click case */
  259.          case 1:
  260.             /* Get selection, which may be either a prefix to a
  261.              * new search path or a filename. DlgDirSelect parses
  262.              * selection, and appends a backslash if selection
  263.              * is a prefix
  264.              */
  265.             DlgDirSelect(hwnd, szFileName, wParam);
  266.             w = lstrlen(szFileName) - 1;
  267.             c = szFileName[w];
  268.             switch (c)
  269.                {
  270.             case ':':
  271.                lstrcat(szFileName, ".");
  272.                break;
  273.  
  274.             case '\\':
  275.  
  276.             case '/':
  277.                szFileName[w] = 0;
  278.                break;
  279.                }
  280.             SetDlgItemText(hwnd, DLGOPEN_EDIT, szFileName);
  281.             break;
  282.          /* Double click case - first click has already been
  283.           * processed as single click
  284.           */
  285.  
  286.          case 2:
  287.             PostMessage(hwnd, WM_COMMAND, IDOK, 0L);
  288.             break;
  289.             }
  290.          break;
  291.  
  292.       case DLGOPEN_EDIT:
  293.          DlgCheckOkEnable(hwnd, DLGOPEN_EDIT, HIWORD(lParam));
  294.          break;
  295.  
  296.       case DLGOPEN_FOLDOUT:
  297.          GetWindowRect(hwnd, &rc);
  298.          GetWindowRect(GetDlgItem(hwnd, DLGOPEN_BIG), &rcCtl);
  299.          if ((rcCtl.left <= rc.right) && (rcCtl.top <= rc.bottom))
  300.             GetWindowRect(GetDlgItem(hwnd, DLGOPEN_SMALL), &rcCtl);
  301.          SetWindowPos(hwnd, NULL, 0, 0, rcCtl.left - rc.left, rc.bottom - rc.
  302.                       top, SWP_NOZORDER | SWP_NOMOVE);
  303.          break;
  304.          }
  305.  
  306.    default:
  307.       return FALSE;
  308.       }
  309.    return TRUE;
  310. }
  311.  
  312. /****************************************************************************
  313.  *                                                                          *
  314.  *  FUNCTION   : static void NEAR DlgCheckOkEnable(hwnd, idEdit, message)   *
  315.  *                                                                          *
  316.  *  PURPOSE    : Enables the <OK> button in a dialog box iff the edit item  *
  317.  *               contains text.                                             *
  318.  *                                                                          *
  319.  ****************************************************************************/
  320.  
  321.  
  322. static void NEAR DlgCheckOkEnable (hwnd, idEdit, message)
  323. HWND hwnd;
  324. int idEdit;
  325. unsigned message;
  326. {
  327.    if (message == EN_CHANGE)
  328.    {
  329.       EnableWindow(GetDlgItem(hwnd, IDOK), (BOOL)SendMessage(GetDlgItem(hwnd,
  330.                    idEdit), WM_GETTEXTLENGTH, 0, 0L));
  331.    }
  332. }
  333.  
  334. /****************************************************************************
  335.  *                                                                          *
  336.  *  FUNCTION   : AddExt (pch, ext)                                          *
  337.  *                                                                          *
  338.  *  PURPOSE    : Add an extension to a filename if none is already specified*
  339.  *                                                                          *
  340.  ****************************************************************************/
  341.  
  342.  
  343. static void NEAR AddExt (pch, ext)
  344. char *pch;    /* File name        */
  345. char *ext;    /* Extension to add */
  346. {
  347.    char acExt[20];
  348.    char *pext = acExt;
  349.  
  350.    while (*ext && *ext != '.')
  351.       ext++;
  352.    while (*ext && *ext != ';')
  353.       *pext++ = *ext++;
  354.    *pext = 0;
  355.    pext = acExt;
  356.    while (*pch == '.')
  357.    {
  358.       pch++;
  359.       if ((*pch == '.') && pch[1] == '\\')
  360.          pch += 2;                       /* ..\ */
  361.       if (*pch == '\\')
  362.          pch++;                         /* .\ */
  363.    }
  364.    while (*pch != '\0')
  365.       if (*pch++ == '.')
  366.          return;
  367.  
  368.    // *pch++ = '.';
  369.    do
  370.       *pch++ = *pext;
  371.    while (*pext++ != '\0');
  372. }
  373. /****************************************************************************
  374.  *                                                                          *
  375.  *  FUNCTION   : FSearchSpec (sz)                                           *
  376.  *                                                                          *
  377.  *  PURPOSE    : Checks to see if NULL-terminated strings contains a "*" or *
  378.  *               a "?".                                                     *
  379.  *                                                                          *
  380.  *  RETURNS    : TRUE  - if the above characters are found in the string    *
  381.  *               FALSE - otherwise.                                         *
  382.  *                                                                          *
  383.  ****************************************************************************/
  384.  
  385.  
  386. static BOOL NEAR FSearchSpec (sz)
  387. char *sz;
  388. {
  389.    for (; *sz; sz++)
  390.    {
  391.       if (*sz == '*' || *sz == '?')
  392.          return TRUE;
  393.    }
  394.    return FALSE;
  395. }
  396.  
  397. /****************************************************************************
  398.  *                                                                          *
  399.  *  FUNCTION   : static char * NEAR FillListBox (hDlg,pFile)                *
  400.  *                                                                          *
  401.  *  PURPOSE    : Fill list box with filenames that match specifications, and*
  402.  *               fills the static field with the path name.                 *
  403.  *                                                                          *
  404.  *  RETURNS    : A pointer to the pathname.                                                           *
  405.  *                                                                          *
  406.  ****************************************************************************/
  407.  
  408.  
  409. static char *NEAR FillListBox (hDlg, pFile)
  410. HWND hDlg;
  411. char *pFile;  /* [path]{list of file wild cards, separated by ';'} */
  412. {
  413.    char ach[20];
  414.    char *pch;
  415.    char *pDir;   /* Directory name or path */
  416.  
  417.    pch = pFile;
  418.    pDir = ach;
  419.    while (*pch && *pch != ';')
  420.       pch++;
  421.    while ((pch > pFile) && (*pch != '/') && (*pch != '\\'))
  422.       pch--;
  423.    if (pch > pFile)
  424.    {
  425.       *pch = 0;
  426.       lstrcpy(pDir, pFile);
  427.       pFile = pch + 1;
  428.    }
  429.    else
  430.    {
  431.       lstrcpy(pDir, ".");
  432.    }
  433.    DlgDirList(hDlg, pDir, DLGOPEN_DIR_LISTBOX, DLGOPEN_PATH, ATTRDIRLIST);
  434.    SendDlgItemMessage(hDlg, DLGOPEN_FILE_LISTBOX, LB_RESETCONTENT, 0, 0L);
  435.    SendDlgItemMessage(hDlg, DLGOPEN_FILE_LISTBOX, WM_SETREDRAW, FALSE, 0L);
  436.    pDir = pFile;            /* save pFile to return */
  437.    while (*pFile)
  438.    {
  439.       pch = ach;
  440.       while (*pFile == ' ')
  441.          pFile++;
  442.       while (*pFile && *pFile != ';')
  443.          *pch++ = *pFile++;
  444.       *pch = 0;
  445.       if (*pFile)
  446.          pFile++;
  447.       SendDlgItemMessage(hDlg, DLGOPEN_FILE_LISTBOX, LB_DIR, ATTRFILELIST, (
  448.                          LONG)(LPSTR)ach);
  449.    }
  450.    SendDlgItemMessage(hDlg, DLGOPEN_FILE_LISTBOX, WM_SETREDRAW, TRUE, 0L);
  451.    InvalidateRect(GetDlgItem(hDlg, DLGOPEN_FILE_LISTBOX), NULL, TRUE);
  452.    return pDir;
  453. }
  454.